package com.tool.engine.export.output;

import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.tool.engine.export.capacity.ExportTaskCapacityLimit;
import com.tool.engine.export.exception.DataOutPutException;
import com.tool.engine.export.task.Task;
import com.tool.engine.export.write.WriteTask;
import com.tool.engine.export.write.excel.ExcelWriteTask;
import com.tool.engine.export.write.excel.ExportTaskExcelOperation;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.util.List;
import java.util.StringJoiner;

@Slf4j
public class ExcelOutputSource implements DataOutputSource {

    private final String filePath;

    private ExcelWriter excelWriter;

    private WriteSheet sheet;

    private Long dataSize=0L;

    private final Task<?> task;

    private final long rowLimit = 1000000;

    private ExportTaskCapacityLimit exportTaskCapacityLimit;

    public ExcelOutputSource(String filePath,Task<?> task) {
        this.filePath = filePath;
        this.task = task;
    }

    @Override
    public void initialize() throws Exception {
        try {
            excelWriter = ExportTaskExcelOperation.createExcelWriter(task.getFileName(), filePath);
            sheet = createSheetBySheetName(task.getSheetName(), 0,task.isDynamic(), task.getHead(), task.getTaskType());
        } catch (IOException e) {
            log.warn("excel data output source initialize error:{}", e.getMessage());
            throw new DataOutPutException(e.getMessage());
        }
    }

    private WriteSheet createNewSheet(WriteSheet sheet, boolean dynamic) {
        if (dataSize >= rowLimit) {
            dataSize = 0L;
            Integer sheetNo = sheet.getSheetNo();
            sheetNo++;
            String sheetNames = new StringJoiner("_").add(sheet.getSheetName()).add(String.valueOf(sheetNo)).toString();
            return createSheetBySheetName(sheetNames, sheetNo, dynamic, sheet.getHead(), sheet.getClazz());
        }
        return sheet;
    }

    private WriteSheet createSheetBySheetName(String sheetName, int sheetNo, boolean dynamic, List<List<String>> head, Class<?> taskType) {
        if (dynamic) {
            return ExportTaskExcelOperation.createExcelSheetByHead(sheetName, sheetNo, head);
        } else {
            return ExportTaskExcelOperation.createExcelSheetByClass(sheetName, sheetNo, taskType);
        }
    }

    @Override
    public WriteTask createWriteTask(List<?> dataList) {
        dataSize += dataList.size();
        sheet = this.createNewSheet(sheet, task.isDynamic());
        return new ExcelWriteTask(dataList, excelWriter, sheet, task.getFileName());
    }

    @Override
    public void complete() {
        if(excelWriter != null){
            ExportTaskExcelOperation.finish(excelWriter);
        }
    }

    @Override
    public void handleError(Exception e) {
    }

    public ExportTaskCapacityLimit getExportTaskCapacityLimit() {
        return exportTaskCapacityLimit;
    }

    public void setExportTaskCapacityLimit(ExportTaskCapacityLimit exportTaskCapacityLimit) {
        this.exportTaskCapacityLimit = exportTaskCapacityLimit;
    }
}
